function [waveformShape,RFE,RFEbyFreq,holdoutRFE,holdoutRFEbyFreq,usedRR]=singleSpikeTrainToLFP(lfp,spikes,parameters)
spikes=bsxfun(@minus,spikes,mean(spikes));
%% Extract parameters
lowFreq=parameters.lowFilterFrequency;
highFreq=parameters.highFilterFrequency;
KernelWidth=parameters.dicionaryTimeSpan;
frequencies=parameters.testingFrequencies;
frequencyBandwidth=parameters.testingFrequencyBandwidth;
samprate=parameters.samplingRate;
numCells=size(spikes,2);
T=numel(lfp);
%% Filter the initial LFP data
if highFreq>50
    filter60HzSignal=true;
else
    filter60HzSignal=false;
end
lfpFilt=filterLFP(lfp',samprate,lowFreq,highFreq,filter60HzSignal)';


if parameters.ridgeRegression=='CV';
    pens=logspace(-4,3,10);
else
    pens=parameters.ridgeRegression;
end
R=numel(pens);
sconvKernels=zeros(2*KernelWidth+1,numCells,R);
sRFE=zeros(numCells,R);
sRFEbyFreq=zeros(numel(parameters.testingFrequencies),numCells,R);
sholdoutRFE1=zeros(numCells,R);
sholdoutRFE2=zeros(numCells,R);
sholdoutRFEbyFreq=zeros(numel(parameters.testingFrequencies),numCells,R);
for r=1:R
    pen=pens(r);
    %% Calculate Convolutional Kernels
    RFE=zeros(numCells,1); % Reduction in Fractional Error
    convKernels=zeros(2*KernelWidth+1,numCells); % Convolutional Kernels
    for n=1:numCells
        [RFE(n),convKernels(:,n)]=timeInvariantSingleCell(lfpFilt,spikes(:,n),KernelWidth,pen);
    end
    %% Calculate LFP predictions from Single Spike Trains
    lfpPred=zeros(numel(lfpFilt),numCells);
    for n=1:numCells
        tmp=conv(spikes(:,n),convKernels(:,n),'full');
        lfpPred(:,n)=tmp(KernelWidth+1:end-KernelWidth);
    end
    %% Calculate RFE by Frequency Bins
    [RFEbyFreq]=calcRFEbyFrequency(repmat(lfpFilt,1,numCells),lfpPred,...
        samprate,frequencies,frequencyBandwidth);waveformShape=convKernels; 
    %% cross-validation
    cv=parameters.numberOfCrossValidationRuns;
    if cv==0
        holdoutRFE=[];
    else
        holdoutRFE=zeros(numCells,1);        
        holdoutRFE1=zeros(numCells,1);        
        holdoutRFE2=zeros(numCells,1);
        Tbin=floor(T/cv);
        lfpBin=reshape(lfpFilt(1:Tbin*cv),Tbin,cv);
        for n=1:numCells;
            spikesBin=reshape(spikes(1:Tbin*cv,n),Tbin,cv);
            [holdoutRFE(n),lfpPred(1:Tbin*cv,n),holdoutRFE1(n),holdoutRFE2(n)]=...
                holdoutRFEfun(lfpBin,spikesBin,KernelWidth,pen);
        end
    end
    [holdoutRFEbyFreq]=calcRFEbyFrequency(repmat(lfpFilt,1,numCells),lfpPred,...
        samprate,frequencies,frequencyBandwidth);
    %% Store variables
    sconvKernels(:,:,r)=convKernels;
    sRFE(:,r)=RFE;
    sRFEbyFreq(:,:,r)=RFEbyFreq;
    sholdoutRFE1(:,r)=holdoutRFE1;
    sholdoutRFE2(:,r)=holdoutRFE2;
    sholdoutRFEbyFreq(:,:,r)=holdoutRFEbyFreq;
end
%%
if R==1
    z=ones(numCells,1);
else
[~,z]=max(sholdoutRFE1');
end
1;
%%
for n=1:numCells
    waveformShape(:,n)=sconvKernels(:,n,z(n));
    RFE(n)=sRFE(n,z(n));
    RFEbyFreq(:,n)=sRFEbyFreq(:,n,z(n));
    holdoutRFE(n)=sholdoutRFE2(n,z(n));
    holdoutRFEbyFreq(:,n)=sholdoutRFEbyFreq(:,n,z(n));
    usedRR=pens(z);
end

function [totalrfe,lfpPred,rfe1,rfe2]=holdoutRFEfun(lfpBin,spikesBin,KernelWidth,pen)
[Tbin,cv]=size(lfpBin);

rfe=zeros(cv,1);
lfpPreds=zeros(size(lfpBin));
for c=1:cv
    lfp=lfpBin(:,[1:c-1,c+1:cv]);lfp=lfp(:);
    spikes=spikesBin(:,[1:c-1,c+1:cv]);spikes=spikes(:);
    [~,convKernel]=timeInvariantSingleCell(lfp,spikes,KernelWidth,pen);
    tmp=conv(spikesBin(:,c),convKernel,'full');
    lfpPred=tmp(KernelWidth+1:end-KernelWidth);
    rfe(c)=sum((lfpBin(:,c)-lfpPred).^2);
    lfpPreds(:,c)=lfpPred;
end
lfpPred=lfpPreds(:);

%%
ra=false(cv,1);ra(datasample(1:cv,floor(cv/2),'Replace',false))=true;
rfe1=1-sum(rfe(ra))./sum(sum(lfpBin(:,ra).^2));
rfe2=1-sum(rfe(~ra))./sum(sum(lfpBin(:,~ra).^2));
totalrfe=1-sum(rfe)./sum(lfpBin(:).^2);















